package com.service.Impl;

import com.dto.PostDTO;
import com.entity.*;
import com.exception.GlobalException;
import com.exception.PostException;
import com.github.pagehelper.PageInfo;
import com.mapper.*;
import com.service.PostService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * ClassName: PostDaoImpl
 * Description:
 *
 * @author L_Z_R
 * @version 1.0
 * @create 2025/04/16 16:29
 */
@Service
public class PostServiceImpl implements PostService {
    @Autowired
    private PostMapper postMapper;
    @Autowired
    private PostMediaMapper postMediaMapper;
    @Autowired
    private PostLocationMapper postLocationMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ConcernMapper concernMapper;
    @Autowired
    private PostCommentMapper postCommentMapper;
    @Autowired
    private PostLikeMapper postLikeMapper;
    @Autowired
    private PlateMapper plateMapper;
    @Autowired
    private CommentLikeMapper commentLikeMapper;


    @Override
    //开启事务,确保帖子信息,媒体信息和地理位置信息同时操作,否则就回滚
    @Transactional(rollbackFor = Exception.class)
    public void addPost(PostDTO postDTO) {
        try {
            //1. 插入帖子表的信息
            postMapper.addPost(postDTO.getPost());

            //2. 插入帖子位置信息
            if (postDTO.getPostLocation() != null && postDTO.getPostLocation().isValid()) {
                PostLocation postLocation = postDTO.getPostLocation();
                postLocation.setPostId(postDTO.getPost().getPostId());
                postLocationMapper.addPostLocation(postLocation);
            }

            //3. 插入帖子媒体信息
            if (postDTO.getPostMedia() != null && postDTO.getPostMedia().isValid()) {
                PostMedia postMedia = postDTO.getPostMedia();
                postMedia.setPostId(postDTO.getPost().getPostId());
                postMediaMapper.addPostMedia(postMedia);
            }
        } catch (Exception e) {
            throw new PostException(1001, "帖子发布失败,请稍后再进行尝试");
        }
    }

    @Override
    public PageInfo<Post> getAllAuditPost(int pageNum, int pageSize) {
        List<Post> allAuditPost = postMapper.getAllAuditPost(pageNum, pageSize);
        allAuditPost.forEach(post -> {
            post.setPlate(plateMapper.getPlateById(post.getPlateId()));
        });
        return new PageInfo<>(allAuditPost);
    }

    @Override
    public void auditPost(Integer postId, Integer auditStatus) {
        try {
            postMapper.auditPost(postId, auditStatus);
        } catch (Exception e) {
            throw new GlobalException(1001, "帖子审核失败,请稍后再进行尝试");
        }

    }

    @Override
    public List<Post> getAllAuditPostByAccountId(Integer accountId) {
        return postMapper.getAllAuditPostByAccountId(accountId);
    }

    @Override
    public List<Post> getAllPostsWithDetails(Integer currentUserId) {
        //1. 查询所有帖子的基本信息
        List<Post> posts = postMapper.selectPosts();
        posts.forEach(post -> enrichPostDetails(post, currentUserId));
        return posts;
    }

    @Override
    public List<Post> getPostsByPlateId(Integer plateId, Integer currentUserId) {
        // 查询对应板块下的所有帖子的基本信息
        List<Post> posts = postMapper.getPostsByPlateId(plateId);
        posts.forEach(post -> enrichPostDetails(post, currentUserId));
        return posts;
    }

    @Override
    public List<Post> getPostsByPostId(Integer postId, Integer currentUserId) {
        return postMapper.getPostsByPostId(postId);
    }

    @Override
    public List<Post> getHotPostsWithDetails(Integer currentUserId) {
        List<Post> hotPosts = postMapper.selectHotPosts();
        hotPosts.forEach(post -> enrichPostDetails(post, currentUserId));
        return hotPosts;
    }

    @Override
    public int getAllPostCount() {
        return postMapper.getAllPostCount();
    }

    @Override
    public void stickPost(Integer postId) {
        try {
            postMapper.stickPost(postId);
        } catch (Exception e) {
            throw new GlobalException(1001, "帖子置顶失败,请稍后进行尝试");
        }
    }

    @Override
    public void essencePost(Integer postId) {
        try {
            postMapper.essencePost(postId);
        } catch (Exception e) {
            throw new GlobalException(1001, "精华帖设置失败,请稍后进行尝试");
        }
    }

    /**
     * 帖子的关联信息构建
     *
     * @param post          帖子详情
     * @param currentUserId 当前用户id
     */
    private void enrichPostDetails(Post post, Integer currentUserId) {
        // 媒体信息
        post.setPostMedia(postMediaMapper.selectPostMediaByPostId(post.getPostId()));

        // 地理位置信息
        post.setPostLocation(postLocationMapper.selectPostLocationByPostId(post.getPostId()));

        //  板块信息
        post.setPlate(plateMapper.getPlateById(post.getPlateId()));

        // 用户信息
        User user = userMapper.selectUserInfoByAccountId(post.getAccountId());
        if(user == null) {
            user = new User();
            user.setNickname("未知用户");
            user.setAvatar("D:\\project\\fish\\fish\\userdefaultavatar\\avatar.jpg");
            post.setUser(user);
        } else {
            post.setUser(user);
        }

        // 关注状态
        if (currentUserId != null) {
            int followStatus = concernMapper.checkFollowStatus(currentUserId, post.getAccountId());
            post.setIsFollowed(followStatus > 0);
        }

        // 获取评论数和点赞数
        post.setLikeCount(postLikeMapper.countPostLikeByPostId(post.getPostId()));
        post.setCommentCount(postCommentMapper.countCommentsByPostId(post.getPostId()));

        // 评论树结构
        post.setComments(buildCommentTree(post.getPostId()));
    }

    //构建评论树形结构
    private List<CommentTree> buildCommentTree(Integer postId) {
        //获取顶级评论
        List<PostComment> topLevelComments = postCommentMapper.selectTopLevelComments(postId);
        List<CommentTree> commentTree = new ArrayList<>();

        for (PostComment comment : topLevelComments) {
            CommentTree treeNode = convertToTree(comment);
            //获取用户信息
            User userInfo = userMapper.selectUserInfoByAccountId(comment.getAccountId());
            if (userInfo != null) {
                treeNode.setUserNickname(userInfo.getNickname());
                treeNode.setUserAvatar(userInfo.getAvatar());
            } else {
                treeNode.setUserNickname("未知用户");
                treeNode.setUserAvatar(null);
            }

            //获取评论的点赞数
            treeNode.setLikeCount(commentLikeMapper.countCommentLikes(comment.getCommentId()));

            //递归获取子评论
            buildChildComments(treeNode);
            commentTree.add(treeNode);
        }
        return commentTree;
    }

    // 递归构建子评论
    private void buildChildComments(CommentTree parentNode) {
        List<PostComment> childComments = postCommentMapper.selectChildComments(parentNode.getCommentId());

        if (childComments != null && !childComments.isEmpty()) {
            List<CommentTree> children = new ArrayList<>();
            for (PostComment comment : childComments) {
                CommentTree childNode = convertToTree(comment);
                // 获取用户信息
                User user = userMapper.selectUserInfoByAccountId(comment.getAccountId());
                if (user != null) {
                    childNode.setUserNickname(user.getNickname());
                    childNode.setUserAvatar(user.getAvatar());
                } else {
                    childNode.setUserNickname("匿名用户");
                    childNode.setUserAvatar(null);
                }
                // 点赞数
                childNode.setLikeCount(commentLikeMapper.countCommentLikes(comment.getCommentId()));
                // 递归
                buildChildComments(childNode);
                children.add(childNode);
            }
            parentNode.setChildren(children);
        }
    }

    // 转换评论为树节点
    private CommentTree convertToTree(PostComment comment) {
        CommentTree treeNode = new CommentTree();
        BeanUtils.copyProperties(comment, treeNode);
        treeNode.setLevel(comment.getParentId() == null || comment.getParentId() == 0 ? 1 : 2); // 简单设置层级
        return treeNode;
    }
}
